from dao.comment import CommentDao
from lib.validator import Validator
from lib.form import Form
from dao.user import UserDao
from dao.post import PostDao

from bson.objectid import ObjectId
from bson.dbref import DBRef
from flask import request
from flask_login import login_user, current_user
import time

from service import Service

class CommentService(Service):
    def __init__(self):
        self.dao = CommentDao()
        self.user_dao = UserDao()
        self.post_dao = PostDao()
    
    def get_comment_list(self):
        comments = []
        _comments = self.dao.all()
        for _comment in _comments:
            author = self.user_dao.find_one({'_id':_comment.author.id})
            
            if _comment.type == 0: # comment
                source = self.post_dao.find_one({'_id':_comment.source.id})
                comments.append({"body":_comment.body, 
                              "to":source.author.username,
                              "mode":'comment', 
                              "author":author.username,
                              "created":_comment.created})
                
            elif _comment.type == 1: # reply
                source = self.dao.find_one({'_id':_comment.source.id})
                comments.append({"body":_comment.body, 
                              "to":source.author.username,
                              "mode":'reply', 
                              "author":author.username,
                              "created":_comment.created})
        return comments
    
    def remove(self, query):
        comment_dao = CommentDao()
        comment = comment_dao.find_one(query)
        if comment is not None:
            comment_dao.remove(comment)

    def submit_comment(self, entry):
        """ Submit entry from the form.
        Arguments:
            entry --- dict type, the dbref field must be Model type
        Return:
            The '_id' value of to_save or [None] if manipulate is False and to_save has no _id field.
        """
        # Comment and reply not allow to update
        _dict = {'body':entry['body'],
             'mode':entry['mode'],
             'created': time.time(),
             'author': DBRef('users', entry['author']._id)}
        
        
        if entry['mode'] == 0: # comment
            source = self.post_dao.find_one({'_id':ObjectId(entry['sid'])})
            _dict['source'] = DBRef('posts', source._id)
        elif entry['mode'] == 1: # reply
            source = self.dao.find_one({'_id':ObjectId(entry['sid'])})
            _dict['source'] = DBRef('comments', source._id)
        
        return self.dao.save(_dict)


class CommentValidator(Validator):
    def __init__(self):
        Validator.__init__(self)
              
        self.rules = {'body': { 
                                'required' : [None, True],
                                'minlength':[None, 1],
                                'maxlength':[None, 256]
                                }
        }

    
class CommentForm(Form):
    """ Submit user form
    """
    def __init__(self):
        """Only accept POST request
        """
        Form.__init__(self)
        self.validator = CommentValidator()
        self.entry = {}
        
        if self.is_submitted():
            inputs = self.get_raw_inputs()
            self.errors = self.validator.validate(inputs)
            if self.errors == []:
                self.entry['sid'] = self.request.values.get('sid')
                self.entry['body'] = self.request.values.get('body')
                self.entry['mode'] = self.request.values.get('mode')
                self.entry['author'] = current_user
                
                
    def has_error(self):
        return self.errors != []